package com.jcfk.system.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jcfk.common.business.service.BaseService;
import com.jcfk.common.core.constant.Constants;
import com.jcfk.common.core.exception.CustomException;
import com.jcfk.common.core.utils.BeanUtils;
import com.jcfk.common.core.utils.IdUtils;
import com.jcfk.common.security.utils.SecurityUtils;
import com.jcfk.common.web.domain.DataPage;
import com.jcfk.common.web.domain.LoginInfo;
import com.jcfk.common.web.domain.RetResult;
import com.jcfk.common.websocket.model.SocketMessage;
import com.jcfk.system.api.utils.LoginUserInfoUtils;
import com.jcfk.system.dao.OaKeyworkTaskDao;
import com.jcfk.system.domain.dto.OaKeyworkInfoDTO;
import com.jcfk.system.domain.dto.OaKeyworkTaskDTO;
import com.jcfk.system.domain.dto.OaKeyworkTaskindexDTO;
import com.jcfk.system.domain.dto.OaKeyworkTaskplanDTO;
import com.jcfk.system.domain.po.*;
import com.jcfk.system.domain.query.OaKeyworkTaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.jcfk.common.core.utils.BeanUtils.convertList;
import static com.jcfk.system.utils.CheckSeqUtils.convertChineseNumberToArabic;
import static com.jcfk.system.utils.RoundNumUtils.RoundNoOf;

/**
 * 重点工作任务
 *
 * @author awei
 * @email 522891237@gqq.com
 * @date 2024-03-26
 */
@Service
public class OaKeyworkTaskService extends BaseService<OaKeyworkTaskDao, OaKeyworkTask> {

    @Autowired
    private OaKeyworkTaskindexService oaKeyworkTaskindexService;

    @Autowired
    private OaKeyworkTaskplanService oaKeyworkTaskplanService;

    @Autowired
    private SysAnnexesFileService sysAnnexesFileService;

    @Autowired
    private OaKeyworkInfoService oaKeyworkInfoService;

    @Autowired
    private SysInternalMessageService sysInternalMessageService;

    @Autowired
    private WebSocketMessageService webSocketMessageService;

    @Autowired
    private OaKeyworkRemindService oaKeyworkRemindService;

    /**
     * OaKeyworkTask分页查询
     *
     * @param page  分页设置
     * @param query 查询条件
     * @return 分页查询结果
     */
    public DataPage<OaKeyworkTaskDTO> queryByPage(DataPage<OaKeyworkTaskDTO> page, OaKeyworkTaskQuery query) {
        // 分页查询
        query.setTaskName(StringUtils.isEmpty(query.getTaskName()) ? query.getTaskName() : "%" + query.getTaskName() + "%");
        query.setLeaderName(StringUtils.isEmpty(query.getLeaderName()) ? query.getLeaderName() : "%" + query.getLeaderName() + "%");
        page = this.baseMapper.queryByPage(page, query);
        return page;
    }

    /**
     * OaKeyworkTaskplan查询 tree
     *
     * @param query 查询条件
     * @return 分页查询结果
     */
    public List<OaKeyworkTaskDTO> tree(OaKeyworkTaskQuery query) {
        // 返回值
        List<OaKeyworkTaskDTO> tree = new ArrayList<>();

        // 查询数据
        List<OaKeyworkTaskDTO> oaKeyworkTaskDTOS = getList(query);
        oaKeyworkTaskDTOS.forEach(obj -> obj.setParent(obj.getParentTaskId()));

        // 子节点结合  根据父节点分组
        Map<String, List<OaKeyworkTaskDTO>> parentChildMap = new HashMap<>();

        // 所有节点
        Map<String, OaKeyworkTaskDTO> maps = new HashMap<>();

        // 所有没有父节点的节点
        List<OaKeyworkTaskDTO> maindto = new ArrayList<>();

        // 查询当前工作下所有的任务
        QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
        taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, query.getKeyworkId());
        List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
        List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

        // 将任务按照 taskid分组
        Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
        for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
            String parentId = node.getTaskId();
            grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        }

        // 查询当前工作下工作计划
        QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
        taskplanQueryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, query.getKeyworkId());
        List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
        List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

        // 将任务计划按照 taskid分组
        Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
        for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
            String parentId = node.getTaskId();
            planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        }


        // 将节点按照父节点进行分组
        for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
            String parentId = node.getParentTaskId();

            parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
            maps.put(node.getId(), node);
        }


        // 获取父节点不存在的子节点
        for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
            if (maps.get(node.getParentTaskId()) == null) {
                maindto.add(node);
            }
        }

        OaKeyworkTaskQuery search = new OaKeyworkTaskQuery();
        search.setKeyworkId(query.getKeyworkId());
        List<OaKeyworkTaskDTO> alllist = getListAll(search);
        alllist.forEach(obj -> obj.setParent(obj.getParentTaskId()));

        Map<String, OaKeyworkTaskDTO> alldtos = new HashMap<>();
        // 将节点按照父节点进行分组
        for (OaKeyworkTaskDTO node : alllist) {
            alldtos.put(node.getId(), node);
        }

        // 父节点赋值
        getParents(maindto, maindto, alldtos);

        oaKeyworkTaskDTOS.addAll(maindto);


        // 去重
        Map<String, OaKeyworkTaskDTO> personMap = new HashMap<>();
        for (OaKeyworkTaskDTO oaKeyworkTaskDTO : oaKeyworkTaskDTOS) {
            personMap.put(oaKeyworkTaskDTO.getId(), oaKeyworkTaskDTO);
        }

        oaKeyworkTaskDTOS = new ArrayList<>(personMap.values());

        Map<String, List<OaKeyworkTaskDTO>> allchilds = new HashMap<>();
        // 将节点按照父节点进行分组
        for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
            String parentId = node.getParentTaskId();
            allchilds.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        }

        // oaKeyworkTaskDTOS = oaKeyworkTaskDTOS.stream().sorted(Comparator.comparing(OaKeyworkTaskDTO::getSeq)).collect(Collectors.toList());
        Collections.sort(oaKeyworkTaskDTOS, new ChineseNumberComparator());

        // buildTree(tree, parentChildMap, maindto);
        for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
            // 判断是否有子节点
            List<OaKeyworkTaskDTO> child = allchilds.get(node.getId());
            if (child != null && child.size() > 0) {
                node.setIshaveSon(true);
            }

            // 数据格式化
            node.setCompletionDegree(RoundNoOf(node.getCompletionDegree(), 0));

            // 任务赋值
            node.setGrossProfits(grossProfitsMap.get(node.getId()));

            // 任务计划赋值
            node.setPlans(planMap.get(node.getId()));
        }
        return oaKeyworkTaskDTOS;
    }


    // 排序规则
    static class ChineseNumberComparator implements Comparator<OaKeyworkTaskDTO> {

        @Override
        public int compare(OaKeyworkTaskDTO str1, OaKeyworkTaskDTO str2) {
            boolean isVersion1 = str1.getSeq().matches("^\\d+(\\.\\d+)*(-[a-zA-Z0-9]+)?$");
            boolean isVersion2 = str2.getSeq().matches("^\\d+(\\.\\d+)*(-[a-zA-Z0-9]+)?$");

            if (isVersion1 && isVersion2) {
                // 如果两个字符串都是版本号格式，按照版本号的方式进行比较
                return compareVersions(str1.getSeq(), str2.getSeq());
            } else if (isVersion1) {
                // 如果第一个字符串是版本号格式，将其排在后面
                return 1;
            } else if (isVersion2) {
                // 如果第二个字符串是版本号格式，将其排在前面
                return -1;
            } else {
                // 如果两个字符串都不是版本号格式，按照中文数字的方式进行比较
                return compareChineseNumbers(str1.getSeq(), str2.getSeq());
            }
        }

        private int compareVersions(String version1, String version2) {
            String[] parts1 = version1.split("[\\.-]");
            String[] parts2 = version2.split("[\\.-]");

            int length = Math.max(parts1.length, parts2.length);
            for (int i = 0; i < length; i++) {
                int part1 = i < parts1.length ? Integer.parseInt(parts1[i]) : 0;
                int part2 = i < parts2.length ? Integer.parseInt(parts2[i]) : 0;

                if (part1 != part2) {
                    return part1 - part2;
                }
            }

            return 0;
        }

        private int compareChineseNumbers(String str1, String str2) {
            int num1 = convertChineseNumberToInteger(str1);
            int num2 = convertChineseNumberToInteger(str2);

            if (num1 != num2) {
                return num1 - num2;
            } else {
                return str1.compareTo(str2);
            }
        }

        private int convertChineseNumberToInteger(String str) {
            return convertChineseNumberToArabic(str);
            // switch (str) {
            //     case "一":
            //         return 1;
            //     case "二":
            //         return 2;
            //     case "三":
            //         return 3;
            //     case "四":
            //         return 4;
            //     case "五":
            //         return 5;
            //     case "六":
            //         return 6;
            //     case "七":
            //         return 7;
            //     case "八":
            //         return 8;
            //     case "九":
            //         return 9;
            //     case "十":
            //         return 10;
            //     case "十一":
            //         return 11;
            //     case "十二":
            //         return 12;
            //     case "十三":
            //         return 13;
            //     case "十四":
            //         return 14;
            //     case "十五":
            //         return 15;
            //     case "十六":
            //         return 16;
            //     case "十七":
            //         return 17;
            //     case "十八":
            //         return 18;
            //     case "十九":
            //         return 19;
            //     case "二十":
            //         return 20;
            //     // 添加更多中文数字的转换
            //     default:
            //         return 0;
        // }
    }
}

// 排序规则

/**
 * OaKeyworkTaskplan查询 tree
 *
 * @param query 查询条件
 * @return 分页查询结果
 */
public List<OaKeyworkTaskDTO> performance(OaKeyworkTaskQuery query) {
    // 返回值
    List<OaKeyworkTaskDTO> tree = new ArrayList<>();

    // 查询数据
    List<OaKeyworkTaskDTO> oaKeyworkTaskDTOS = getList(query);
    oaKeyworkTaskDTOS.forEach(obj -> obj.setParent(obj.getParentTaskId()));

    // 子节点结合  根据父节点分组
    Map<String, List<OaKeyworkTaskDTO>> parentChildMap = new HashMap<>();

    // 所有节点
    Map<String, OaKeyworkTaskDTO> maps = new HashMap<>();

    // 所有没有父节点的节点
    List<OaKeyworkTaskDTO> maindto = new ArrayList<>();

    // 查询当前工作下所有的任务
    QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
    List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

    // 将任务按照 taskid分组
    Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
    for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
        String parentId = node.getTaskId();
        grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 查询当前工作下工作计划
    QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
    taskplanQueryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
    List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

    // 将任务计划按照 taskid分组
    Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
    for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
        String parentId = node.getTaskId();
        planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        String parentId = node.getParentTaskId();

        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        maps.put(node.getId(), node);
    }


    // 获取父节点不存在的子节点
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        if (maps.get(node.getParentTaskId()) == null) {
            maindto.add(node);
        }

        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));

        // 任务计划赋值
        node.setPlans(planMap.get(node.getId()));
    }

    OaKeyworkTaskQuery search = new OaKeyworkTaskQuery();
    search.setKeyworkId(query.getKeyworkId());
    List<OaKeyworkTaskDTO> alllist = getListAll(search);
    alllist.forEach(obj -> obj.setParent(obj.getParentTaskId()));

    Map<String, OaKeyworkTaskDTO> alldtos = new HashMap<>();
    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : alllist) {
        alldtos.put(node.getId(), node);
    }

    // 父节点赋值
    getParents(maindto, maindto, alldtos);

    oaKeyworkTaskDTOS.addAll(maindto);


    // buildTree(tree, parentChildMap, maindto);
    // 去重
    Map<String, OaKeyworkTaskDTO> personMap = new HashMap<>();
    for (OaKeyworkTaskDTO oaKeyworkTaskDTO : oaKeyworkTaskDTOS) {
        personMap.put(oaKeyworkTaskDTO.getId(), oaKeyworkTaskDTO);
    }

    oaKeyworkTaskDTOS = new ArrayList<>(personMap.values());

    Map<String, List<OaKeyworkTaskDTO>> allchilds = new HashMap<>();
    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        String parentId = node.getParentTaskId();
        allchilds.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 排序
    // oaKeyworkTaskDTOS = oaKeyworkTaskDTOS.stream().sorted(Comparator.comparing(OaKeyworkTaskDTO::getSeq)).collect(Collectors.toList());
    Collections.sort(oaKeyworkTaskDTOS, new ChineseNumberComparator());

    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        // 判断是否有子节点
        List<OaKeyworkTaskDTO> child = allchilds.get(node.getId());
        if (child != null && child.size() > 0) {
            node.setIshaveSon(true);
        }

        // 数据格式化
        node.setCompletionDegree(RoundNoOf(node.getCompletionDegree(), 0));

        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));

        // 任务计划赋值
        node.setPlans(planMap.get(node.getId()));
    }

    return oaKeyworkTaskDTOS;
}

/**
 * OaKeyworkTaskplan查询 tree
 *
 * @param query 查询条件
 * @return 分页查询结果
 */
public List<OaKeyworkTaskDTO> performanceNotPimss(OaKeyworkTaskQuery query) {
    // 返回值
    List<OaKeyworkTaskDTO> tree = new ArrayList<>();

    // 查询数据
    List<OaKeyworkTaskDTO> oaKeyworkTaskDTOS = getListNotPimss(query);
    oaKeyworkTaskDTOS.forEach(obj -> obj.setParent(obj.getParentTaskId()));

    // 子节点结合  根据父节点分组
    Map<String, List<OaKeyworkTaskDTO>> parentChildMap = new HashMap<>();

    // 所有节点
    Map<String, OaKeyworkTaskDTO> maps = new HashMap<>();

    // 所有没有父节点的节点
    List<OaKeyworkTaskDTO> maindto = new ArrayList<>();

    // 查询当前工作下所有的任务
    QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
    List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

    // 将任务按照 taskid分组
    Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
    for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
        String parentId = node.getTaskId();
        grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 查询当前工作下工作计划
    QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
    taskplanQueryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
    List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

    // 将任务计划按照 taskid分组
    Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
    for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
        String parentId = node.getTaskId();
        planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        String parentId = node.getParentTaskId();

        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        maps.put(node.getId(), node);
    }


    // 获取父节点不存在的子节点
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        if (maps.get(node.getParentTaskId()) == null) {
            maindto.add(node);
        }
    }

    OaKeyworkTaskQuery search = new OaKeyworkTaskQuery();
    search.setKeyworkId(query.getKeyworkId());
    List<OaKeyworkTaskDTO> alllist = getListAll(search);
    alllist.forEach(obj -> obj.setParent(obj.getParentTaskId()));

    Map<String, OaKeyworkTaskDTO> alldtos = new HashMap<>();
    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : alllist) {
        alldtos.put(node.getId(), node);
    }

    // 父节点赋值
    getParents(maindto, maindto, alldtos);

    oaKeyworkTaskDTOS.addAll(maindto);

    // buildTree(tree, parentChildMap, maindto);
    oaKeyworkTaskDTOS.addAll(maindto);

    // 去重
    Map<String, OaKeyworkTaskDTO> personMap = new HashMap<>();
    for (OaKeyworkTaskDTO oaKeyworkTaskDTO : oaKeyworkTaskDTOS) {
        personMap.put(oaKeyworkTaskDTO.getId(), oaKeyworkTaskDTO);
    }

    oaKeyworkTaskDTOS = new ArrayList<>(personMap.values());

    // 排序
    oaKeyworkTaskDTOS = oaKeyworkTaskDTOS.stream().sorted(Comparator.comparing(OaKeyworkTaskDTO::getSeq)).collect(Collectors.toList());
    Collections.sort(oaKeyworkTaskDTOS, new ChineseNumberComparator());

    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));

        // 任务计划赋值
        node.setPlans(planMap.get(node.getId()));
    }

    return oaKeyworkTaskDTOS;
}

/**
 * OaKeyworkTaskplan查询 tree
 *
 * @param query 查询条件
 * @return 分页查询结果
 */
public List<OaKeyworkTaskDTO> userTree(OaKeyworkTaskQuery query) {
    // 返回值
    List<OaKeyworkTaskDTO> tree = new ArrayList<>();
    // 查询数据
    List<OaKeyworkTaskDTO> oaKeyworkTaskDTOS = getUserList(query);
    oaKeyworkTaskDTOS.forEach(obj -> obj.setParent(obj.getParentTaskId()));

    // 子节点结合  根据父节点分组
    Map<String, List<OaKeyworkTaskDTO>> parentChildMap = new HashMap<>();

    // 所有节点
    Map<String, OaKeyworkTaskDTO> maps = new HashMap<>();

    // 所有没有父节点的节点
    List<OaKeyworkTaskDTO> maindto = new ArrayList<>();


    List<String> taskIds = oaKeyworkTaskDTOS.stream().map(OaKeyworkTaskDTO::getId).collect(Collectors.toList());

    Map<String, String> oamap = new HashMap<>();
    List<String> keyworkIds = oaKeyworkTaskDTOS.stream().map(OaKeyworkTaskDTO::getKeyworkId).collect(Collectors.toList());
    if (keyworkIds.size() > 0) {
        QueryWrapper<OaKeyworkInfo> oaKeyworkInfoQueryWrapper = new QueryWrapper<>();
        oaKeyworkInfoQueryWrapper.lambda().in(OaKeyworkInfo::getId, keyworkIds);
        List<OaKeyworkInfo> list = oaKeyworkInfoService.list(oaKeyworkInfoQueryWrapper);

        // 将任务计划按照 taskid分组
        for (OaKeyworkInfo node : list) {
            oamap.put(node.getId(), node.getWorkName());
        }
    }


    Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
    Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
    // 查询当前工作下所有的任务
    if (taskIds.size() > 0) {
        QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
        taskindexQueryWrapper.lambda().in(OaKeyworkTaskindex::getTaskId, taskIds);
        List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
        List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

        // 将任务按照 taskid分组

        for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
            String parentId = node.getTaskId();
            grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        }

        // 查询当前工作下工作计划
        QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
        taskplanQueryWrapper.lambda().in(OaKeyworkTaskplan::getTaskId, taskIds);
        List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
        List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

        // 将任务计划按照 taskid分组
        for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
            String parentId = node.getTaskId();
            planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        }
    }

    Collections.sort(oaKeyworkTaskDTOS, new ChineseNumberComparator());

    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        node.setKeyworkName(oamap.get(node.getKeyworkId()));
        String parentId = node.getParentTaskId();

        node.setCompletionDegree(RoundNoOf(node.getCompletionDegree(), 0));

        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        maps.put(node.getId(), node);
    }


    // 获取父节点不存在的子节点
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));

        // 任务计划赋值
        node.setPlans(planMap.get(node.getId()));

        if (maps.get(node.getParentTaskId()) == null) {
            maindto.add(node);
        }
    }

    buildTree(tree, parentChildMap, maindto);
    Map<String, List<OaKeyworkTaskDTO>> map = new HashMap<>();
    Map<String, String> names = new HashMap<>();
    Map<String, String> years = new HashMap<>();
    for (OaKeyworkTaskDTO node : tree) {
        names.put(node.getKeyworkId(), node.getKeyworkName());
        map.computeIfAbsent(node.getKeyworkId(), k -> new ArrayList<>()).add(node);
    }

    List<OaKeyworkTaskDTO> rettree = new ArrayList<>();
    for (Map.Entry<String, List<OaKeyworkTaskDTO>> entry : map.entrySet()) {
        OaKeyworkTaskDTO dto = new OaKeyworkTaskDTO();
        dto.setChildren(map.get(entry.getKey()));
        dto.setKeyworkId(entry.getKey());
        dto.setKeyworkName(names.get(entry.getKey()));
        rettree.add(dto);
    }
    return tree;
}


/**
 * OaKeyworkTaskplan查询 tree
 *
 * @param query 查询条件
 * @return 分页查询结果
 */
public List<OaKeyworkTaskDTO> treeNotPimss(OaKeyworkTaskQuery query) {
    // 返回值
    List<OaKeyworkTaskDTO> tree = new ArrayList<>();

    // 查询数据
    List<OaKeyworkTaskDTO> oaKeyworkTaskDTOS = getListNotPimss(query);
    oaKeyworkTaskDTOS.forEach(obj -> obj.setParent(obj.getParentTaskId()));

    // 子节点结合  根据父节点分组
    Map<String, List<OaKeyworkTaskDTO>> parentChildMap = new HashMap<>();

    // 所有节点
    Map<String, OaKeyworkTaskDTO> maps = new HashMap<>();

    // 所有没有父节点的节点
    List<OaKeyworkTaskDTO> maindto = new ArrayList<>();

    // 查询当前工作下所有的任务
    QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
    List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

    // 将任务按照 taskid分组
    Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
    for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
        String parentId = node.getTaskId();
        grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 查询当前工作下工作计划
    QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
    taskplanQueryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
    List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

    // 将任务计划按照 taskid分组
    Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
    for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
        String parentId = node.getTaskId();
        planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        String parentId = node.getParentTaskId();

        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
        maps.put(node.getId(), node);
    }


    // 获取父节点不存在的子节点
    for (OaKeyworkTaskDTO node : oaKeyworkTaskDTOS) {
        if (maps.get(node.getParentTaskId()) == null) {
            maindto.add(node);
        }

        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));

        // 任务计划赋值
        node.setPlans(planMap.get(node.getId()));
    }

    // buildTree(tree, parentChildMap, maindto);
    return oaKeyworkTaskDTOS;
}

/**
 * OaKeyworkTaskplan查询 t
 *
 * @param id 查询条件
 * @return 子节点
 */
public List<OaKeyworkTaskDTO> sons(String id) {

    OaKeyworkTask task = this.getById(id);

    QueryWrapper<OaKeyworkTask> qw = new QueryWrapper<>();
    qw.lambda().eq(OaKeyworkTask::getKeyworkId, task.getKeyworkId());
    qw.lambda().eq(OaKeyworkTask::getParentTaskId, task.getId());
    qw.lambda().eq(OaKeyworkTask::getDeleted, 0);

    List<OaKeyworkTask> list = super.list(qw);

    List<OaKeyworkTaskDTO> dtos = convertList(list, OaKeyworkTaskDTO.class);

    List<String> pids = dtos.stream().map(OaKeyworkTaskDTO::getId).collect(Collectors.toList());

    Map<String, List<OaKeyworkTask>> map = new HashMap<>();
    // 查询子节点是否有子节点
    if (pids.size() > 0) {
        QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OaKeyworkTask::getKeyworkId, task.getKeyworkId());
        queryWrapper.lambda().in(OaKeyworkTask::getParentTaskId, pids);
        queryWrapper.lambda().eq(OaKeyworkTask::getDeleted, 0);

        List<OaKeyworkTask> sons = super.list(queryWrapper);
        for (OaKeyworkTask son : sons) {
            map.computeIfAbsent(son.getParentTaskId(), k -> new ArrayList<>()).add(son);
        }
    }
    // 查询当前工作下所有的任务
    QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, task.getKeyworkId());
    List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
    List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

    // 将任务按照 taskid分组
    Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
    for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
        String parentId = node.getTaskId();
        grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 查询当前工作下工作计划
    QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
    taskplanQueryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, task.getKeyworkId());
    List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
    List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

    // 将任务计划按照 taskid分组
    Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
    for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
        String parentId = node.getTaskId();
        planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    dtos.forEach(obj -> {
        List<OaKeyworkTask> child = map.get(obj.getId());
        if (child != null && child.size() > 0) {
            obj.setIshaveSon(true);
        }

        obj.setCompletionDegree(RoundNoOf(obj.getCompletionDegree(), 0));

        obj.setParent(obj.getParentTaskId());
        // 任务赋值
        obj.setGrossProfits(grossProfitsMap.get(obj.getId()));

        // 任务计划赋值
        obj.setPlans(planMap.get(obj.getId()));
    });

    Collections.sort(dtos, new ChineseNumberComparator());

    return dtos;
}

/**
 * OaKeyworkTaskplan查询 tree
 *
 * @param query 查询条件
 * @return 分页查询结果
 */
public Map<String, Object> bulletinBoard(OaKeyworkTaskQuery query) {
    // 返回值
    List<OaKeyworkTaskDTO> tree = new ArrayList<>();

    List<OaKeyworkTaskDTO> alllist = getListAll(query);
    alllist.forEach(obj -> obj.setParent(obj.getParentTaskId()));
    Collections.sort(alllist, new ChineseNumberComparator());

    // 所有没有父节点的节点
    List<OaKeyworkTaskDTO> maindto = new ArrayList<>();

    // 查询当前工作下所有的任务
    QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);
    List<OaKeyworkTaskindexDTO> oaKeyworkTaskindexDTOS = convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class);

    // 将任务按照 taskid分组
    Map<String, List<OaKeyworkTaskindexDTO>> grossProfitsMap = new HashMap<>();
    for (OaKeyworkTaskindexDTO node : oaKeyworkTaskindexDTOS) {
        String parentId = node.getTaskId();
        grossProfitsMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 查询当前工作下工作计划
    QueryWrapper<OaKeyworkTaskplan> taskplanQueryWrapper = new QueryWrapper<>();
    taskplanQueryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, query.getKeyworkId());
    List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(taskplanQueryWrapper);
    List<OaKeyworkTaskplanDTO> oaKeyworkTaskplanDTOS = convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class);

    // 将任务计划按照 taskid分组
    Map<String, List<OaKeyworkTaskplanDTO>> planMap = new HashMap<>();
    for (OaKeyworkTaskplanDTO node : oaKeyworkTaskplanDTOS) {
        String parentId = node.getTaskId();
        planMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 所有节点
    Map<String, OaKeyworkTaskDTO> maps = alllist.stream().collect(Collectors.toMap(OaKeyworkTaskDTO::getId, entity -> entity));

    Map<String, List<OaKeyworkTaskDTO>> childMap = new HashMap<>();
    for (OaKeyworkTaskDTO node : alllist) {
        String parentId = node.getParentTaskId();
        childMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
    }

    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : alllist) {
        if (maps.get(node.getParentTaskId()) == null) {
            maindto.add(node);
        }
        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));

        // 任务计划赋值
        node.setPlans(planMap.get(node.getId()));
    }


    Map<String, OaKeyworkTaskDTO> alldtos = new HashMap<>();
    // 将节点按照父节点进行分组
    for (OaKeyworkTaskDTO node : alllist) {
        alldtos.put(node.getId(), node);
    }


    // 任務看板附賦值
    Collections.sort(alllist, new ChineseNumberComparator());
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
    SimpleDateFormat nianFormat = new SimpleDateFormat("yyyy");
    List<String> times = new ArrayList<>();

    Map<String, List<OaKeyworkTaskDTO>> parentChildMap = new HashMap<>();

    for (OaKeyworkTaskDTO node : alllist) {
        List<OaKeyworkTaskDTO> child = childMap.get(node.getId());

        // 数据格式化
        node.setCompletionDegree(RoundNoOf(node.getCompletionDegree(), 0));

        if (child != null && child.size() > 0) {
            node.setIshaveSon(true);
        }

        parentChildMap.computeIfAbsent(node.getParentTaskId(), k -> new ArrayList<>()).add(node);
        // 任务赋值
        node.setGrossProfits(grossProfitsMap.get(node.getId()));
        if (node.getPlanStartDate() != null) times.add(dateFormat.format(node.getPlanStartDate()));
        if (node.getPlanEndDate() != null) times.add(dateFormat.format(node.getPlanEndDate()));
        if (planMap.get(node.getId()) != null && planMap.get(node.getId()).size() > 0) {

            TreeMap<String, OaKeyworkTaskplanDTO> listMap = new TreeMap<>();
            List<OaKeyworkTaskplanDTO> list = planMap.get(node.getId());

            List<String> years = new ArrayList<>();
            List<List<String>> months = new ArrayList<>();
            List<List<String>> percents = new ArrayList<>();

            // 获得所有年月数据
            for (OaKeyworkTaskplanDTO oaKeyworkTaskplanDTO : list) {
                String formattedDate = dateFormat.format(oaKeyworkTaskplanDTO.getPlanFinishDate());
                times.add(formattedDate);
                String year = nianFormat.format(oaKeyworkTaskplanDTO.getPlanFinishDate());
                years.add(year);
                OaKeyworkTaskplanDTO getdetp = listMap.get(formattedDate);
                if (getdetp != null) {
                    BigDecimal decimal1 = new BigDecimal(getdetp.getCompletionDegree());
                    BigDecimal decimal2 = new BigDecimal(oaKeyworkTaskplanDTO.getCompletionDegree());

                    int result = decimal1.compareTo(decimal2);
                    if (result < 0) {
                        listMap.put(formattedDate, oaKeyworkTaskplanDTO);
                    }
                } else {
                    listMap.put(formattedDate, oaKeyworkTaskplanDTO);
                }
            }

            Set<String> uniqueSet = new HashSet<>(years);

            years = new ArrayList<>(uniqueSet);

            String latsYear = "";
            List<String> yearofmonths = new ArrayList<>();
            List<String> percentsOfyearandmonths = new ArrayList<>();
            for (Map.Entry<String, OaKeyworkTaskplanDTO> entry : listMap.entrySet()) {
                String[] keyset = entry.getKey().split("-");
                if (!latsYear.equals(keyset[0])) {
                    if (!StringUtils.isEmpty(latsYear)) {
                        months.add(yearofmonths);
                        percents.add(percentsOfyearandmonths);
                    }
                    latsYear = keyset[0];
                    yearofmonths = new ArrayList<>();
                    percentsOfyearandmonths = new ArrayList<>();
                }
                yearofmonths.add(keyset[1]);

                String key = entry.getKey();
                OaKeyworkTaskplanDTO value = entry.getValue();
                percentsOfyearandmonths.add(value.getCompletionDegree());
                System.out.println("Key: " + key + ", Value: " + value);
            }

            if (listMap.size() > 0) {
                months.add(yearofmonths);
                percents.add(percentsOfyearandmonths);
            }
            node.setPlans(planMap.get(node.getId()));
            node.setYears(years);
            node.setMonths(months);
            node.setPercents(percents);
        }
    }
    String minYearMonth = "";
    String maxYearMonth = "";
    if (times.size() > 0) {
        minYearMonth = Collections.min(times, Comparator.comparing(OaKeyworkTaskService::parseYearMonth));
        maxYearMonth = Collections.max(times, Comparator.comparing(OaKeyworkTaskService::parseYearMonth));
    }

    // 子节点结合  根据父节点分组
    buildTree(tree, parentChildMap, maindto);

    Map<String, Object> objectMap = new HashMap<>();
    objectMap.put("minYearMonth", minYearMonth);
    objectMap.put("maxYearMonth", maxYearMonth);
    objectMap.put("list", tree);

    return objectMap;
}

private static int parseYearMonth(String yearMonth) {
    String[] parts = yearMonth.split("-");
    int year = Integer.parseInt(parts[0]);
    int month = Integer.parseInt(parts[1]);
    return year * 12 + month;
}


/**
 * 根据条件获取用户分页列表
 *
 * @param tree           树
 * @param parentChildMap 节点集合
 * @param maindto        父id
 */
private static void buildTree(List<OaKeyworkTaskDTO> tree, Map<String, List<OaKeyworkTaskDTO>> parentChildMap, List<OaKeyworkTaskDTO> maindto) {
    if (maindto != null) {
        for (OaKeyworkTaskDTO child : maindto) {
            List<OaKeyworkTaskDTO> grandchildren = parentChildMap.get(child.getId());
            if (grandchildren != null) {
                buildTree(child.getChildren(), parentChildMap, child.getId());
            }
            tree.add(child);
        }
    }
}

/**
 * 根据条件获取用户分页列表
 *
 * @param maindto 父id
 */
private void getParents(List<OaKeyworkTaskDTO> maindto, List<OaKeyworkTaskDTO> retDto, Map<String, OaKeyworkTaskDTO> alldtos) {
    if (maindto != null && maindto.size() > 0) {
        List<OaKeyworkTaskDTO> dtoList = new ArrayList<>();
        for (OaKeyworkTaskDTO oaKeyworkTaskDTO : maindto) {
            if (!oaKeyworkTaskDTO.getParentTaskId().equals("0") && alldtos.get(oaKeyworkTaskDTO.getParentTaskId()) != null)
                dtoList.add(alldtos.get(oaKeyworkTaskDTO.getParentTaskId()));
        }

        if (dtoList.size() > 0) {
            retDto.addAll(dtoList);
            if (dtoList.size() > 0) getParents(dtoList, retDto, alldtos);
        }
    }
}

/**
 * 根据条件获取用户分页列表
 *
 * @param tree           树
 * @param parentChildMap 节点集合
 * @param parentId       父id
 */
private static void buildTree(List<OaKeyworkTaskDTO> tree, Map<String, List<OaKeyworkTaskDTO>> parentChildMap, String parentId) {
    List<OaKeyworkTaskDTO> children = parentChildMap.get(parentId);
    if (children != null) {
        for (OaKeyworkTaskDTO child : children) {
            List<OaKeyworkTaskDTO> grandchildren = parentChildMap.get(child.getId());
            if (grandchildren != null) {
                buildTree(child.getChildren(), parentChildMap, child.getId());
            }
            tree.add(child);
        }
    }
}


/**
 * 判断OaKeyworkTask是已经存在
 *
 * @param dto
 * @return
 */
public RetResult<String> isValid(OaKeyworkTaskDTO dto) {
    QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();

    return RetResult.ok();
}

/**
 * 插入重点工作任务
 *
 * @param dto 插入对象
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public void insert(OaKeyworkTaskDTO dto) {

    // 保存
    OaKeyworkTask item = new OaKeyworkTask();
    BeanUtils.copyProperties(dto, item);
    item.setId(IdUtils.simpleUUID());

    this.setDefaultValue(item);
    setAllInfo(item);
    super.save(item);


    // 计算完成率
    // 向上赋值
    if (item.getTaskType().equals("1")) {
        QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OaKeyworkTask::getParentTaskId, item.getParentTaskId()).groupBy(OaKeyworkTask::getParentTaskId);
        queryWrapper.lambda().eq(OaKeyworkTask::getDeleted, 0);
        queryWrapper.select("ROUND( AVG( completion_degree ), 2 ) completion_degree");
        OaKeyworkTask oaKeyworkTask = this.getOne(queryWrapper);

        // 修改完成率
        if (oaKeyworkTask != null) {
            OaKeyworkTask task = this.getById(item.getParentTaskId());
            if (task != null) {
                task.setCompletionDegree(oaKeyworkTask.getCompletionDegree());
                this.updateById(task);
            }
        }
    }
    if (dto.getLeaderId() != null) {
        OaKeyworkInfoDTO keyworkInfoDTO = oaKeyworkInfoService.get(dto.getKeyworkId());
        String tiile = "您收到了关于《" + keyworkInfoDTO.getWorkName() + " - " + dto.getTaskName() + "》的工作任务";
        sendMessage(item, tiile);
    }

    // 任务
    oaKeyworkTaskindexService.saveBatch(dto.getGrossProfits(), item.getId(), dto.getKeyworkId());
    // 计划
    oaKeyworkTaskplanService.saveBatch(dto.getPlans(), item.getId(), dto.getKeyworkId());
    // 附件
    sysAnnexesFileService.saveBatch(dto.getFiles(), item.getId(), "work_task_file");
}


// 发送消息
public void sendMessage(OaKeyworkTask dto, String tille) {
    OaKeyworkRemind oaKeyworkRemind = new OaKeyworkRemind();
    oaKeyworkRemind.setRemindType("1");
    oaKeyworkRemind.setTaskId(dto.getId());
    oaKeyworkRemind.setKeyworkId(dto.getKeyworkId());
    oaKeyworkRemind.setReceiveUserId(dto.getLeaderId());
    oaKeyworkRemind.setRemindContent(tille);
    oaKeyworkRemindService.setDefaultValue(oaKeyworkRemind);
    oaKeyworkRemindService.save(oaKeyworkRemind);

    // 接受消息入库
    SysInternalMessage message = new SysInternalMessage();
    message.setTitle("工作任务助手");
    message.setUrl("/workbench/sysmessage");
    message.setMsgBody(tille);
    message.setSendTime(new Date());
    message.setRecevieUserId(dto.getLeaderId());
    message.setReaded(Constants.NO);
    message.setEnabled(Constants.YES);
    message.setSendTime(new Date());
    message.setSendUserId(SecurityUtils.getUserId());
    message.setCreatedUserId(SecurityUtils.getUserId());
    message.setCreatedUserName(SecurityUtils.getUserName());
    message.setCreateTime(new Date());

    // 入库
    sysInternalMessageService.save(message);

    SocketMessage socketMessage = new SocketMessage();
    socketMessage.setMessageType("internalMessage");
    socketMessage.setUrl(message.getUrl());
    socketMessage.setMsgId(message.getId());
    socketMessage.setMessageContent("工作任务助手");
    socketMessage.setMessageLevel("INFO");
    webSocketMessageService.sendMessage(message.getRecevieUserId(), socketMessage);
}


/**
 * 插入重点工作任务
 *
 * @param dto 插入对象
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public void updataPlan(OaKeyworkTaskDTO dto) {
    // 保存
    OaKeyworkTask item = new OaKeyworkTask();
    BeanUtils.copyProperties(dto, item);

    // 默认数据
    this.setDefaultValue(item);

    setAllInfo(item);

    super.updateById(item);

    // 计划
    oaKeyworkTaskplanService.saveBatch(dto.getPlans(), item.getId(), item.getKeyworkId());

    sysAnnexesFileService.saveBatch(dto.getFiles(), dto.getId(), "work_task_file");
}

/**
 * 插入重点工作任务
 *
 * @param dto 插入对象
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public void updataGrossProfits(OaKeyworkTaskDTO dto) {
    // 保存
    OaKeyworkTask item = new OaKeyworkTask();
    BeanUtils.copyProperties(dto, item);

    // 默认数据
    this.setDefaultValue(item);

    setAllInfo(item);

    super.updateById(item);
    // 任务
    oaKeyworkTaskindexService.saveBatch(dto.getGrossProfits(), item.getId(), item.getKeyworkId());

    sysAnnexesFileService.saveBatch(dto.getFiles(), dto.getId(), "work_task_file");
}

/**
 * 更新重点工作任务
 *
 * @param dto 更新对象
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public void update(OaKeyworkTaskDTO dto) {

    // 保存
    OaKeyworkTask item = new OaKeyworkTask();
    BeanUtils.copyProperties(dto, item);

    // 默认数据
    this.setDefaultValue(item);

    setAllInfo(item);

    super.updateById(item);

    // 计算完成率
    // 向上赋值
    if (item.getTaskType().equals("1")) {
        if (!StringUtils.isEmpty(item.getCompletionDegree())) {
            QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(OaKeyworkTask::getParentTaskId, item.getParentTaskId()).groupBy(OaKeyworkTask::getParentTaskId);
            queryWrapper.lambda().eq(OaKeyworkTask::getDeleted, 0);
            queryWrapper.select("ROUND( AVG( completion_degree ), 2 ) completion_degree");
            OaKeyworkTask oaKeyworkTask = this.getOne(queryWrapper);

            // 修改完成率
            if (oaKeyworkTask != null) {
                OaKeyworkTask task = this.getById(item.getParentTaskId());
                if (task != null) {
                    task.setCompletionDegree(oaKeyworkTask.getCompletionDegree());
                    this.updateById(task);
                }
            }
        }
    }

    // 任务
    oaKeyworkTaskindexService.saveBatch(dto.getGrossProfits(), dto.getId(), dto.getKeyworkId());
    // 计划
    oaKeyworkTaskplanService.saveBatch(dto.getPlans(), dto.getId(), dto.getKeyworkId());
    // 附件
    sysAnnexesFileService.saveBatch(dto.getFiles(), item.getId(), "work_task_file");
}

/**
 * 更新重点工作任务
 *
 * @param dto 更新对象
 * @return
 */
@Transactional(rollbackFor = Exception.class)
public void updateTask(OaKeyworkTaskDTO dto) {

    // 保存
    OaKeyworkTask item = new OaKeyworkTask();
    BeanUtils.copyProperties(dto, item);

    // 默认数据
    this.setDefaultValue(item);

    setAllInfo(item);

    super.updateById(item);

    // 计算完成率
    // 向上赋值
    if (item.getTaskType().equals("1")) {
        if (!StringUtils.isEmpty(item.getCompletionDegree())) {
            QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(OaKeyworkTask::getParentTaskId, item.getParentTaskId()).groupBy(OaKeyworkTask::getParentTaskId);
            queryWrapper.lambda().eq(OaKeyworkTask::getDeleted, 0);
            queryWrapper.select("ROUND( AVG( completion_degree ), 2 ) completion_degree");
            OaKeyworkTask oaKeyworkTask = this.getOne(queryWrapper);

            // 修改完成率
            if (oaKeyworkTask != null) {
                OaKeyworkTask task = this.getById(item.getParentTaskId());
                if (task != null) {
                    task.setCompletionDegree(oaKeyworkTask.getCompletionDegree());
                    this.updateById(task);
                }
            }
        }
    }

    if (dto.getLeaderId() != null) {
        String tiile = "您收到了关于《" + dto.getTaskName() + "》变更的工作任务";
        sendMessage(item, tiile);
    }

    // 任务
    oaKeyworkTaskindexService.saveBatch(dto.getGrossProfits(), dto.getId(), dto.getKeyworkId());
    // 计划
    oaKeyworkTaskplanService.saveBatch(dto.getPlans(), dto.getId(), dto.getKeyworkId());
    // 附件
    sysAnnexesFileService.saveBatch(dto.getFiles(), item.getId(), "work_task_file");
}


/**
 * 设置添加默认值
 *
 * @param item 添加对象
 */
public void setDefaultValue(OaKeyworkTask item) {
    if (StrUtil.isEmpty(item.getCreatedUserId())) {
        item.setCreatedUserId(SecurityUtils.getUserId());
        item.setCreateTime(new Date());
        item.setCreatedUserName(SecurityUtils.getUserName());
    }
    item.setLastUpdatedUserId(SecurityUtils.getUserId());
    item.setLastUpdateTime(new Date());
    item.setLastUpdatedUserName(SecurityUtils.getUserName());
}

/**
 * 根据主键获取重点工作任务信息
 *
 * @param id 主键
 * @return StandardCodeDTO
 */
public OaKeyworkTaskDTO get(String id) {
    // 查询数据
    OaKeyworkTask item = this.baseMapper.selectById(id);
    OaKeyworkTaskDTO dto = new OaKeyworkTaskDTO();
    try {
        BeanUtils.copyProperties(item, dto);
    } catch (RuntimeException e) {
        throw e;
    }

    QueryWrapper<OaKeyworkTaskplan> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(OaKeyworkTaskplan::getTaskId, item.getId());
    queryWrapper.lambda().eq(OaKeyworkTaskplan::getKeyworkId, item.getKeyworkId());
    List<OaKeyworkTaskplan> oaKeyworkTaskplans = oaKeyworkTaskplanService.list(queryWrapper);
    dto.setPlans(convertList(oaKeyworkTaskplans, OaKeyworkTaskplanDTO.class));


    QueryWrapper<OaKeyworkTaskindex> taskindexQueryWrapper = new QueryWrapper<>();
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getTaskId, item.getId());
    taskindexQueryWrapper.lambda().eq(OaKeyworkTaskindex::getKeyworkId, item.getKeyworkId());
    List<OaKeyworkTaskindex> oaKeyworkTaskindices = oaKeyworkTaskindexService.list(taskindexQueryWrapper);

    dto.setGrossProfits(convertList(oaKeyworkTaskindices, OaKeyworkTaskindexDTO.class));

    // 附件列表
    dto.setFiles(sysAnnexesFileService.getList(item.getId(), "work_task_file"));


    QueryWrapper<OaKeyworkTask> oaKeyworkTaskQueryWrapper = new QueryWrapper<>();
    oaKeyworkTaskQueryWrapper.lambda().eq(OaKeyworkTask::getParentTaskId, id);
    oaKeyworkTaskQueryWrapper.lambda().eq(OaKeyworkTask::getDeleted, 0);
    long count = this.baseMapper.selectCount(oaKeyworkTaskQueryWrapper);
    if (count > 0) dto.setIshaveSon(true);

    return dto;
}


/**
 * 根据条件获取单表信息列表
 *
 * @param query 查询条件
 * @return List<OaKeyworkTaskDTO>
 */
public List<OaKeyworkTaskDTO> getList(OaKeyworkTaskQuery query) {
    LoginInfo loginInfo = LoginUserInfoUtils.getUserInfo();

    // 查询条件
    QueryWrapper<OaKeyworkTask> qw = new QueryWrapper<>();
    qw.lambda().eq(!StrUtil.isEmpty(query.getKeyworkId()), OaKeyworkTask::getKeyworkId, query.getKeyworkId());
    qw.lambda().like(!StrUtil.isEmpty(query.getTaskName()), OaKeyworkTask::getTaskName, query.getTaskName());
    qw.lambda().eq(!StrUtil.isEmpty(query.getTaskType()), OaKeyworkTask::getTaskType, query.getTaskType());
    qw.lambda().eq(!StrUtil.isEmpty(query.getLeaderId()), OaKeyworkTask::getLeaderId, query.getLeaderId());
    qw.lambda().like(!StrUtil.isEmpty(query.getLeaderName()), OaKeyworkTask::getLeaderName, query.getLeaderName());
    qw.lambda().ge(!StrUtil.isEmpty(query.getStartDateStart()), OaKeyworkTask::getStartDate, query.getStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getStartDateEnd()), OaKeyworkTask::getStartDate, query.getStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getEndDateStart()), OaKeyworkTask::getEndDate, query.getEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getEndDateEnd()), OaKeyworkTask::getEndDate, query.getEndDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanStartDateStart()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanStartDateEnd()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanEndDateStart()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanEndDateEnd()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateEnd());
    qw.lambda().eq(!StrUtil.isEmpty(query.getWorkStatus()), OaKeyworkTask::getWorkStatus, query.getWorkStatus());
    qw.lambda().eq(OaKeyworkTask::getDeleted, 0);


    // 超级管理员
    if (!"superadmin".equals(loginInfo.getUserType())) {
        OaKeyworkInfoDTO oaKeyworkInfoDTO = oaKeyworkInfoService.get(query.getKeyworkId());
        if (oaKeyworkInfoDTO == null || !oaKeyworkInfoDTO.getCreatedUserId().equals(loginInfo.getUserId())) {
            QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.and(wapper -> wapper.eq("leader_id", loginInfo.getUserId()).or().eq("created_user_id", loginInfo.getUserId()));
            queryWrapper.lambda().eq(!StrUtil.isEmpty(query.getKeyworkId()), OaKeyworkTask::getKeyworkId, query.getKeyworkId());
            List<OaKeyworkTask> userlist = super.list(queryWrapper);
            List<String> ids = userlist.stream().map(OaKeyworkTask::getAllIds).collect(Collectors.toList());
            if (ids.size() <= 0) return new ArrayList<>();

            if (ids.size() > 0) {
                qw.lambda().and(wapper -> {
                    for (String id : ids) {
                        wapper.or().likeRight(OaKeyworkTask::getAllIds, id);
                    }
                });
            }
        }
    }

    // 查询数据
    List<OaKeyworkTask> list = super.list(qw);

    return convertList(list, OaKeyworkTaskDTO.class);
}


/**
 * 根据条件获取单表信息列表
 *
 * @param query 查询条件
 * @return List<OaKeyworkTaskDTO>
 */
public List<OaKeyworkTaskDTO> getListAll(OaKeyworkTaskQuery query) {
    LoginInfo loginInfo = LoginUserInfoUtils.getUserInfo();

    // 查询条件
    QueryWrapper<OaKeyworkTask> qw = new QueryWrapper<>();
    qw.lambda().eq(!StrUtil.isEmpty(query.getKeyworkId()), OaKeyworkTask::getKeyworkId, query.getKeyworkId());
    qw.lambda().like(!StrUtil.isEmpty(query.getTaskName()), OaKeyworkTask::getTaskName, query.getTaskName());
    qw.lambda().eq(!StrUtil.isEmpty(query.getTaskType()), OaKeyworkTask::getTaskType, query.getTaskType());
    qw.lambda().eq(!StrUtil.isEmpty(query.getLeaderId()), OaKeyworkTask::getLeaderId, query.getLeaderId());
    qw.lambda().like(!StrUtil.isEmpty(query.getLeaderName()), OaKeyworkTask::getLeaderName, query.getLeaderName());
    qw.lambda().ge(!StrUtil.isEmpty(query.getStartDateStart()), OaKeyworkTask::getStartDate, query.getStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getStartDateEnd()), OaKeyworkTask::getStartDate, query.getStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getEndDateStart()), OaKeyworkTask::getEndDate, query.getEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getEndDateEnd()), OaKeyworkTask::getEndDate, query.getEndDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanStartDateStart()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanStartDateEnd()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanEndDateStart()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanEndDateEnd()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateEnd());
    qw.lambda().eq(!StrUtil.isEmpty(query.getWorkStatus()), OaKeyworkTask::getWorkStatus, query.getWorkStatus());
    qw.lambda().eq(OaKeyworkTask::getDeleted, 0);

    // 查询数据
    List<OaKeyworkTask> list = super.list(qw);

    return convertList(list, OaKeyworkTaskDTO.class);
}


/**
 * 根据条件获取单表信息列表
 *
 * @param query 查询条件
 * @return List<OaKeyworkTaskDTO>
 */
public List<OaKeyworkTaskDTO> getUserList(OaKeyworkTaskQuery query) {
    LoginInfo loginInfo = LoginUserInfoUtils.getUserInfo();

    // 查询条件
    QueryWrapper<OaKeyworkTask> qw = new QueryWrapper<>();
    qw.lambda().eq(!StrUtil.isEmpty(query.getKeyworkId()), OaKeyworkTask::getKeyworkId, query.getKeyworkId());
    qw.lambda().like(!StrUtil.isEmpty(query.getTaskName()), OaKeyworkTask::getTaskName, query.getTaskName());
    qw.lambda().eq(!StrUtil.isEmpty(query.getTaskType()), OaKeyworkTask::getTaskType, query.getTaskType());
    qw.lambda().eq(!StrUtil.isEmpty(query.getLeaderId()), OaKeyworkTask::getLeaderId, query.getLeaderId());
    qw.lambda().like(!StrUtil.isEmpty(query.getLeaderName()), OaKeyworkTask::getLeaderName, query.getLeaderName());
    qw.lambda().ge(!StrUtil.isEmpty(query.getStartDateStart()), OaKeyworkTask::getStartDate, query.getStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getStartDateEnd()), OaKeyworkTask::getStartDate, query.getStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getEndDateStart()), OaKeyworkTask::getEndDate, query.getEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getEndDateEnd()), OaKeyworkTask::getEndDate, query.getEndDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanStartDateStart()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanStartDateEnd()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanEndDateStart()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanEndDateEnd()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateEnd());
    qw.lambda().eq(!StrUtil.isEmpty(query.getWorkStatus()), OaKeyworkTask::getWorkStatus, query.getWorkStatus());
    qw.lambda().eq(OaKeyworkTask::getDeleted, 0);
    qw.lambda().orderByAsc(OaKeyworkTask::getKeyworkId);


    // 超级管理员
    if (!"superadmin".equals(loginInfo.getUserType())) {
        qw.and(wapper -> wapper.eq("leader_id", loginInfo.getUserId()).or().eq("created_user_id", loginInfo.getUserId()));
    }

    // 查询数据
    List<OaKeyworkTask> list = super.list(qw);

    return convertList(list, OaKeyworkTaskDTO.class);
}


/**
 * 根据条件获取单表信息列表
 *
 * @param query 查询条件
 * @return List<OaKeyworkTaskDTO>
 */
public List<OaKeyworkTaskDTO> getListNotPimss(OaKeyworkTaskQuery query) {
    // 查询条件
    QueryWrapper<OaKeyworkTask> qw = new QueryWrapper<>();
    qw.lambda().eq(!StrUtil.isEmpty(query.getKeyworkId()), OaKeyworkTask::getKeyworkId, query.getKeyworkId());
    qw.lambda().like(!StrUtil.isEmpty(query.getTaskName()), OaKeyworkTask::getTaskName, query.getTaskName());
    qw.lambda().eq(!StrUtil.isEmpty(query.getTaskType()), OaKeyworkTask::getTaskType, query.getTaskType());
    qw.lambda().eq(!StrUtil.isEmpty(query.getLeaderId()), OaKeyworkTask::getLeaderId, query.getLeaderId());
    qw.lambda().like(!StrUtil.isEmpty(query.getLeaderName()), OaKeyworkTask::getLeaderName, query.getLeaderName());
    qw.lambda().ge(!StrUtil.isEmpty(query.getStartDateStart()), OaKeyworkTask::getStartDate, query.getStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getStartDateEnd()), OaKeyworkTask::getStartDate, query.getStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getEndDateStart()), OaKeyworkTask::getEndDate, query.getEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getEndDateEnd()), OaKeyworkTask::getEndDate, query.getEndDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanStartDateStart()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanStartDateEnd()), OaKeyworkTask::getPlanStartDate, query.getPlanStartDateEnd());
    qw.lambda().ge(!StrUtil.isEmpty(query.getPlanEndDateStart()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateStart());
    qw.lambda().le(!StrUtil.isEmpty(query.getPlanEndDateEnd()), OaKeyworkTask::getPlanEndDate, query.getPlanEndDateEnd());
    qw.lambda().eq(!StrUtil.isEmpty(query.getWorkStatus()), OaKeyworkTask::getWorkStatus, query.getWorkStatus());
    qw.lambda().eq(OaKeyworkTask::getDeleted, 0);

    // 查询数据
    List<OaKeyworkTask> list = super.list(qw);

    return convertList(list, OaKeyworkTaskDTO.class);
}


/**
 * 设置全主键、全编码、全名称
 */
public void setAllInfo(OaKeyworkTask item) {
    QueryWrapper<OaKeyworkTask> qw = new QueryWrapper<>();
    qw.lambda().eq(OaKeyworkTask::getId, item.getParentTaskId());

    OaKeyworkTask superCustomMultilevelKind = this.baseMapper.selectOne(qw);
    if (superCustomMultilevelKind == null) {
        item.setAllIds(item.getId());
        item.setAllNames(item.getTaskName());
    } else {
        item.setAllIds(superCustomMultilevelKind.getAllIds() + "," + item.getId());
        item.setAllNames(superCustomMultilevelKind.getAllNames() + "," + item.getTaskName());
    }
}

public void delete(String id) {
    OaKeyworkTask item = new OaKeyworkTask();

    // 判断有没有子节点
    QueryWrapper<OaKeyworkTask> sonQueryWrapper = new QueryWrapper<>();
    sonQueryWrapper.lambda().eq(OaKeyworkTask::getDeleted, 0);
    sonQueryWrapper.lambda().eq(OaKeyworkTask::getParentTaskId, id);

    long sons = count(sonQueryWrapper);
    if (sons > 0) {
        throw new CustomException("该节点不能直接删除，请先删除子节点！");
    }

    this.setDefaultValue(item);
    item.setDeleted(1);

    QueryWrapper<OaKeyworkTask> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("id", id);

    this.update(item, queryWrapper);
}

}

